home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Internet Info 1994 March
/
Internet Info CD-ROM (Walnut Creek) (March 1994).iso
/
networking
/
ip
/
ka9q
/
bmdist.arc
/
SEND.C
< prev
next >
Wrap
C/C++ Source or Header
|
1988-10-13
|
12KB
|
529 lines
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <ctype.h>
#if (defined(UNIX) || defined(MICROSOFT))
#include <sys/types.h>
#endif
#include "bm.h"
struct addr *addrecip();
char *ptime();
/* send a message */
dosmtpsend(mfp,toargs,nargs,subject)
FILE *mfp;
char *toargs[];
int nargs;
char *subject;
{
char smtp_subject[LINELEN],
tstring[LINELEN];
char *tmpnam();
FILE *fpin;
char *p;
char *tf = "bmXXXXXX"; /* temp file name */
int c;
int n;
long sequence;
struct addr *tolist,*tp;
register FILE *tfile;
time_t t;
if (nargs == 0) {
printf("No recpients\n");
return 0;
}
fpin = mfp;
if ((tolist = make_tolist(nargs,toargs)) == NULLADDR) {
printf("Send aborted\n");
return 0;
}
sequence = get_msgid();
time(&t);
mktemp(tf);
/* open textfile for write */
if ((tfile = fopen(tf,"w+")) == NULLFILE) {
perror(tf);
del_addrlist(tolist);
return 1;
}
if (!qflag) {
/* write RFC822-compatible headers using above information */
fprintf(tfile,"Date: %s",ptime(&t));
fprintf(tfile,"Message-Id: <%ld@%s>\n",sequence,hostname);
fprintf(tfile,"From: %s@%s",username,hostname);
if (fullname != NULLCHAR && *fullname != '\0')
fprintf(tfile," (%s)",fullname);
fprintf(tfile,"\n");
if (replyto != NULLCHAR && *replyto != '\0')
fprintf(tfile,"Reply-To: %s\n",replyto);
strcpy(tstring,"To: ");
for (tp = tolist; tp != NULLADDR; tp = tp->next) {
strcat(tstring,tp->user);
if (tp->host != NULLCHAR || *tp->host != '\0') {
strcat(tstring,"@");
strcat(tstring,tp->host);
}
n = strlen(tstring);
if (tp->next) {
if (n > 50) {
fprintf(tfile,"%s,\n\t",tstring);
if (tty) printf("%s,\n ",tstring);
*tstring = '\0';
} else
strcat(tstring,", ");
}
}
fprintf(tfile,"%s\n",tstring);
if (tty) printf("%s\n",tstring);
*smtp_subject = '\0';
if (subject == NULL && tty) {
/* prompt and get Subject: */
printf("Subject: ");
gets(smtp_subject);
} else {
strcpy(smtp_subject,subject);
if(tty) printf("Subject: %s\n",smtp_subject);
}
fprintf(tfile,"Subject: %s\n",smtp_subject);
fprintf(tfile,"\n"); /* add empty line as separator */
}
if (!tty && fpin == NULLFILE)
fpin = stdin;
if (fpin != NULLFILE ) {
while((c = getc(fpin)) != EOF)
if(putc(c,tfile) == EOF)
break;
if (ferror(tfile)) {
perror("tmp file");
(void) fclose(tfile);
return 1;
}
} else {
/* sending a message not from a file */
/* copy text from console to the file */
printf("\nType message text. Enter a '.' or ctrl/D in column one to end.");
printf("\nCommands: ~p - redisplay msg, ~e - invoke editor, ~? - help\n\n");
for(;;) {
/* read line from console ie stdin */
if (gets(tstring) == NULLCHAR)
break;
rip(tstring);
if(strcmp(tstring,".") == 0 || tstring[0] == '\004')
break;
if (*tstring == '~' ) {
switch(tstring[1]) {
case 'p':
/* Print the message so far */
fseek(tfile,0L,0);
while (fgets(tstring,sizeof(tstring),tfile) != NULLCHAR)
fputs(tstring,stdout);
break;
case 'e':
/* Drop into editor */
(void) fclose(tfile);
if (editor == NULLCHAR) {
printf("No editor defined\n");
break;
}
sprintf(tstring,"%s %s",editor,tf);
/* call editor to enter message text */
if (system(tstring))
printf("unable to invoke editor\n");
tfile = fopen(tf,"a+");
break;
case 'q':
(void) fclose(tfile);
(void) unlink(tf);
printf("Abort\n");
return 0;
case 'r':
{
FILE *infl;
p = &tstring[2];
while(*p == ' ' || *p == '\t')
p++;
if (*p == '\0')
printf("No file name specified\n");
else
if((infl = fopen(p,"r")) == NULLFILE)
printf("No such file\n");
else {
printf("Reading file %s\n",p);
while((c = getc(infl)) != EOF)
if(putc(c,tfile) == EOF)
break;
if (ferror(tfile)) {
perror("tmp file");
(void) fclose(tfile);
return 1;
}
(void) fclose(infl);
}
break;
}
case 'm':
{
int msg;
p = &tstring[2];
while(*p == ' ' || *p == '\t')
p++;
if (*p == '\0')
msg = current;
else
msg = atoi(p);
if (mfile == NULLFILE || msg < 1 || msg > nmsgs)
printf("no such message\n");
else {
printf("Inserting message %d\n",msg);
msgtofile(msg,tfile,0);
}
break;
}
case '~':
fprintf(tfile,"%s\n",&tstring[1]);
break;
case '?':
printf("~e - Invoke Editor\n");
printf("~p - Display message buffer\n");
printf("~q - Abort this message\n");
printf("~r file - Read file into buffer\n");
printf("~m msg - message into buffer\n");
printf("~~ - Enter a ~ into message\n");
break;
default:
printf("Unknown ~ escape. ~? for help\n");
}
printf("(continue)\n");
} else
fprintf(tfile,"%s\n",tstring);
}
printf("EOF\n");
}
queuejob(tfile,tolist);
recordmsg(tfile,tolist->user); /* save copy for sender */
(void) fclose(tfile);
del_addrlist(tolist);
(void) unlink(tf);
return 0;
}
/* forward a message in its orginal form */
bouncemsg(mfp,toargs,nargs)
FILE *mfp;
char *toargs[];
int nargs;
{
struct addr *list;
if (nargs == 0) {
printf("No recpients\n");
} else if ((list = make_tolist(nargs,toargs)) == NULLADDR) {
printf("Bad to list\n");
} else {
queuejob(mfp,list);
del_addrlist(list);
}
return 0;
}
/* Return Date/Time in Arpanet format in passed string */
/* Print out the time and date field as
* "DAY day MONTH year hh:mm:ss ZONE"
*/
char *
ptime(t)
long *t;
{
register struct tm *ltm;
struct tm *localtime();
static char tz[4];
static char str[40];
extern char *getenv();
char *p;
static char *days[7] = {
"Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
static char *months[12] = {
"Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec" };
/* Read the system time */
ltm = localtime(t);
if (*tz == '\0')
if ((p = getenv("TZ")) == NULL)
strcpy(tz,"GMT");
else
strncpy(tz,p,3);
/* rfc 822 format */
sprintf(str,"%s, %.2d %s %02d %02d:%02d:%02d %.3s\n",
days[ltm->tm_wday],
ltm->tm_mday,
months[ltm->tm_mon],
ltm->tm_year,
ltm->tm_hour,
ltm->tm_min,
ltm->tm_sec,
tz);
return(str);
}
/* save copy in the record file */
recordmsg(dfile,to)
FILE *dfile;
char *to;
{
register int c;
FILE *fp;
time_t t;
if (record == NULLCHAR)
return 1;
fseek(dfile,0L,0);
if ((fp = fopen(record,"a")) == NULLFILE) {
printf("Unable to append to %s\n",record);
} else {
(void) time(&t);
fprintf(fp,"From %s %s",to,ctime(&t));
while((c = getc(dfile)) != EOF)
if(putc(c,fp) == EOF)
break;
if (ferror(fp)) {
(void) fclose(fp);
return 1;
}
(void) fclose(fp);
}
return 0;
}
/* place a mail job in the outbound queue */
int
queuejob(dfile,tolist)
FILE *dfile;
struct addr *tolist;
{
FILE *fp;
char tmpstring[50];
register struct addr *tp,*sp;
char prefix[9];
int c;
long id;
for (tp = tolist; tp != NULLADDR; tp = tp->next) {
if (tp->sent)
continue;
fseek(dfile,0L,0);
id = get_msgid();
sprintf(prefix,"%ld",id);
(void) mlock(mqueue,prefix);
sprintf(tmpstring,"%s/%s.txt",mqueue,prefix);
if((fp = fopen(tmpstring,"w")) == NULLFILE) {
printf("unable to open %s\n",tmpstring);
(void) rmlock(mqueue,prefix);
return 1;
}
while((c = getc(dfile)) != EOF)
if(putc(c,fp) == EOF)
break;
if (ferror(fp)) {
(void) fclose(fp);
(void) rmlock(mqueue,prefix);
return 1;
}
(void) fclose(fp);
sprintf(tmpstring,"%s/%s.wrk",mqueue,prefix);
if((fp = fopen(tmpstring,"w")) == NULLFILE) {
(void) rmlock(mqueue,prefix);
return 1;
}
fprintf(fp,"%s\n%s@%s\n",tp->host,username,hostname);
fprintf(fp,"%s@%s\n",tp->user,tp->host);
tp->sent++;
/* find and other addresses to the same host */
for (sp = tp->next; sp != NULLADDR; sp = sp->next) {
if (sp->sent)
continue;
if (strcmp(tp->host,sp->host) == 0) {
fprintf(fp,"%s@%s\n",sp->user,sp->host);
sp->sent++;
}
}
(void) fclose(fp);
(void) rmlock(mqueue,prefix);
}
return 0;
}
#define SKIPWORD(X) while(*X && *X!=' ' && *X!='\t' && *X!='\n' && *X!= ',') X++;
#define SKIPSPACE(X) while(*X ==' ' || *X =='\t' || *X =='\n' || *X == ',') X++;
/* check for and alias and expand alais into a address list */
struct addr *
expandalias(head, user)
struct addr **head;
char *user;
{
FILE *fp;
register char *s,*p,*h;
int inalias;
struct addr *tp;
char buf[LINELEN];
fp = fopen(alias, "r");
/* no alias file found */
if (fp == NULLFILE)
return addrecip(head, user, hostname);
inalias = 0;
while (fgets(buf,LINELEN,fp) != NULLCHAR) {
p = buf;
if ( *p == '#' || *p == '\0')
continue;
rip(p);
/* if not in an matching entry skip continuation lines */
if (!inalias && isspace(*p))
continue;
/* when processing an active alias check for a continuation */
if (inalias) {
if (!isspace(*p))
break; /* done */
} else {
s = p;
SKIPWORD(p);
*p++ = '\0'; /* end the alias name */
if (strcmp(s,user) != 0)
continue; /* no match go on */
inalias = 1;
}
/* process the recipients on the alias line */
SKIPSPACE(p);
while(*p != '\0' && *p != '#') {
s = p;
SKIPWORD(p);
if (*p != '\0')
*p++ = '\0';
/* find hostname */
if ((h = strchr(s,'@')) != NULLCHAR)
*h++ = '\0';
else
h = hostname;
tp = addrecip(head,s,h);
SKIPSPACE(p);
}
}
(void) fclose(fp);
if (inalias) /* found and processed and alias. */
return tp;
/* no alias found treat as a local address */
return addrecip(head, user, hostname);
}
/* convert a arg list to an list of address structures */
struct addr *
make_tolist(argc,argv)
int argc;
char *argv[];
{
struct addr *tolist, *tp;
char *user, *host;
int i;
tolist = NULLADDR;
for (i = 0; i < argc; i++) {
user = argv[i];
if ((host = strchr(user ,'@')) != NULLCHAR) {
*host++ = '\0';
/* if it matches our host name */
if (stricmp(host,hostname) == 0)
host = NULLCHAR;
}
if (host == NULLCHAR) /* a local address */
tp = expandalias(&tolist,user);
else /* a remote address */
tp = addrecip(&tolist, user, host);
if (tp == NULLADDR) {
printf("Out of memory\n");
del_addrlist(tolist);
return NULLADDR;
}
}
return tolist;
}
/* delete a list of mail addresses */
del_addrlist(list)
struct addr *list;
{
struct addr *tp, *tp1;;
for (tp = list; tp != NULLADDR; tp = tp1) {
tp1 = tp->next;
if (tp->user != NULLCHAR);
free(tp->user);
if (tp->host != NULLCHAR);
free(tp->host);
(void) free((char *)tp);
}
}
/* add an address to the from of the list pointed to by head
** return NULLADDR if out of memory.
*/
struct addr *
addrecip(head,user,host)
struct addr **head;
char *user, *host;
{
register struct addr *tp;
tp = (struct addr *)calloc(1,sizeof(struct addr));
if (tp == NULLADDR)
return NULLADDR;
tp->next = NULLADDR;
/* allocate storage for the user's login */
if ((tp->user = malloc((unsigned)strlen(user)+1)) == NULLCHAR) {
(void) free((char *)tp);
return NULLADDR;
}
strcpy(tp->user,user);
/* allocate storage for the host name */
if (host != NULLCHAR)
if ((tp->host = malloc((unsigned)strlen(host)+1)) == NULLCHAR) {
(void) free(tp->user);
(void) free((char *)tp);
return NULLADDR;
}
strcpy(tp->host,host);
/* add entry to front of existing list */
if (*head == NULLADDR)
*head = tp;
else {
tp->next = *head;
*head = tp;
}
return tp;
}